{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Outputting HTML in a notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Display Helpers\n",
    "\n",
    "There are a number of helper methods for writing HTML that are available by default in a .NET notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "using static Microsoft.DotNet.Interactive.Formatting.PocketViewTags;\n",
    "using Microsoft.DotNet.Interactive.Formatting;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### HTML"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want to write out a `string` as HTML, you can use the `HTML` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "display(HTML(\"<b style=\\\"color:blue\\\">Hello!</b>\"));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Displaying HTML using a `string` directly will display the actual string rather than rendering it as HTML. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "display(\"<b style=\\\"color:blue\\\">Hello!</b>\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `HTML` method signals that the content is HTML because its return type, `HtmlString`, implements `IHtmlContent`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "var someHtml = HTML(\"<b style=\\\"color:blue\\\">Hello!</b>\");\n",
    "\n",
    "display(someHtml.GetType());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Javascript"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You may also want to output JavaScript. You can do this using the `Javascript` helper."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "Javascript(@\"alert(\"\"Hello!\"\");\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PocketView (C#)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For more complex HTML, you can use the PocketView API. Lets start with an example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "display(\n",
    "    span(\n",
    "        img[src:\"https://en.wikipedia.org/favicon.ico\", style:\"height:1.5em\"],\n",
    "        a[href: @\"https://en.wikipedia.org\", target: \"blank\", style:\"color:green\"](b(\"Wikipedia\"))\n",
    "    )\n",
    ");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "PocketView is an API for concisely writing HTML, in the terminology of HTML, using C# code. Just like the `HTML` method, it returns an object that implements `IHtmlContent`. You can see the actual HTML code by converting a `PocketView` to a string:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "var pocketView = span(\n",
    "        img[src:\"https://en.wikipedia.org/favicon.ico\", style:\"height:1.5em\"],\n",
    "        a[href: @\"https://en.wikipedia.org\", target: \"blank\", style:\"color:green\"](b(\"Wikipedia\")));\n",
    "\n",
    "display(pocketView.ToString());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The PocketView API provides a number of top-level properties in your notebook that can be used to create various HTML tags. Here's the list of tags that are supported by default:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "var pocketViewTagMethods = typeof(PocketViewTags)\n",
    "    .GetProperties()\n",
    "    .Select(m => m.Name);\n",
    "\n",
    "display(pocketViewTagMethods);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each of these properties returns a `PocketView` instance that can then be filled in with some content by passing arguments to it like a method call."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "var pocketView = i(\"Hello!\");\n",
    "\n",
    "display(pocketView);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A `PocketView` instance can also be decorated with attributes using square brackets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "var pocketView = span[style:\"font-style:italic\"](\"Hello!\");\n",
    "\n",
    "display(pocketView);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You'll notice that if you pass a `string` to `PocketView`, it will be HTML encoded for you:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "PocketView pocketView = span(\"<div>This string looks like HTML but it will be HTML encoded.</div>\");\n",
    "\n",
    "display(pocketView);\n",
    "\n",
    "display(\"Have a look at the actual HTML:\");\n",
    "\n",
    "display(pocketView.ToString());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you don't want the content to be encoded, simply pass it wrapped in a type that implements `IHtmlContent`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "var htmlContent = HTML(\"<i>This won't be HTML encoded.</i>\");\n",
    "\n",
    "PocketView pocketView = span(\n",
    "    htmlContent\n",
    ");\n",
    "\n",
    "display(pocketView);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can pass other types of objects of into a `PocketView` as well. When you do this, they're formatted using the plain text formatter, which by default expands the object's properties."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "PocketView pocketView = b(\n",
    "    new { Fruit = \"apple\", Texture = \"smooth\" }\n",
    ");\n",
    "\n",
    "display(pocketView);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Magic Commands\n",
    "\n",
    "There are also several magic commands that can be used to output HTML in your .NET notebook.\n",
    "\n",
    "You can output HTML..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "html"
    }
   },
   "outputs": [],
   "source": [
    "#!html\n",
    "<b>Hello!</b>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...or run JavaScript..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "javascript"
    }
   },
   "outputs": [],
   "source": [
    "#!javascript\n",
    "alert(\"hello\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...or render Markdown."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "#!markdown\n",
    "\n",
    "Write a **list** ...\n",
    "* first\n",
    "* second\n",
    "\n",
    "...or a _table_...\n",
    "\n",
    "|Fruit    |Texture |\n",
    "|---------|--------|\n",
    "|apple    |smooth  |\n",
    "|durian   |bumpy   |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "**_See also_**\n",
    "* [Object formatters](Object%20formatters.ipynb)\n",
    "* [Displaying output](Displaying%20output.ipynb)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "file_extension": ".cs",
   "mimetype": "text/x-csharp",
   "name": "C#",
   "pygments_lexer": "csharp",
   "version": "8.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}